import io, socket, threading
import ui
from . import adb, speech
port = 19887 # 手机代理端口
conn = None # socket对象
def connect(): # 连接手机的tts服务
    def start():
        global conn
        # 打开socket
        conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 设置socket保活选项
        conn.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, True)
        # 开始连接
        conn.connect_ex(('127.0.0.1', port,))
        # 启动子线程接收消息
        threading.Thread(target = recv).start()
        ui.message(_('已连接'))
    # adb端口映射，把手机的某个端口与本主机关联，这样本地的port实际上是个代理端口
    adb.forward(port, port + 1, start)
def recv(): # 子线程函数，用来接收消息
    global conn
    buf = io.BytesIO() # 缓冲区变量
    while conn:
        try:
            char = conn.recv(1) # 读取一个字符
            if char == b'\x00':
                # 如果字符遇到\0控制字符，表示字符串完毕，让语音库朗读缓冲区，并且清空缓冲区
                speak(buf.getvalue().decode())
                buf.close()
                buf = io.BytesIO()
            if char == b'\x05':
                # 如果收到0x05控制字符，这是一个保活用的 ping 字节，就忽略并且网服务端写入响应字节0x06
                conn.send(b'\x06')
            else:
                buf.write(char)
        except OSError:
            disconnect()
            continue
    # 使用完毕缓冲区要记得关闭
    buf.close()
def disconnect(): # 断开连接
    global conn
    if conn:
        conn.close()
        ui.message(_('已断开'))
    conn = None
def switch():
    # 切换连接状态
    global conn
    if conn:
        disconnect()
    else:
        connect()
def speak(text):
    # 语音输出
    if not text:return
    speech.cancel()
    speech.speak(text)
